Git Action (CD)
NOTE
GitHub Actions를 이용한 CD(지속적 배포) 정리. 별도 러너 서버에서 빌드 → Docker 이미지 생성 → Docker Hub push → 배포 서버 SSH 배포까지의 흐름과 워크플로우 예시.
📌 개념
GitHub Actions 배포 흐름
GitHub Actions는 별도의 러너(runner) 서버에서 실행된다.
- 레포지토리의 업데이트 내용을 받는다 (Actions 러너)
- 빌드를 진행한다 (Actions 러너)
- Dockerfile로 Docker 이미지를 생성한다 (Actions 러너)
- Docker 이미지를 Docker Hub에 push 한다 (Actions 러너)
이후 배포 단계:
- Actions 러너에서 SSH로 배포 서버에 접속
- 기존 Docker 컨테이너 종료 및 삭제 (배포 서버)
- Docker Hub에서 이미지 pull
docker run으로 컨테이너 기동
- 민감 값은 GitHub Secrets(
${{ secrets.* }})로 저장·사용
YAML | 연산자 (블록 스칼라)
|는 여러 줄을 개행을 유지한 채 하나의 문자열로 넘긴다.
run: |
echo "Hello World"
echo "End"
# 실행 결과
# Hello World
# EndIMPORTANT
YAML의 파이프(
|)와 리눅스 셸의 파이프(|)는 의미가 다르다. 리눅스 파이프는 이전 명령의 출력을 다음 명령의 입력으로 넘긴다.
echo "Hello World" | cat
# 실행 결과
# Hello World💻 예시
AWS + Docker 배포 워크플로우
name: Deploy to AWS with Docker
on:
push:
branches:
- master
pull_request:
branches:
- master
jobs:
build-and-deploy:
name: Build JAR, Create Docker Image & Deploy
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '17'
- name: Build JAR with Gradle
run: |
chmod +x gradlew
./gradlew clean build -x test
- name: Build Docker Image
run: |
docker buildx build -t ${{ secrets.DOCKER_HUB_USERNAME }}/backend-server:latest .
- name: Login to Docker Hub
run: |
echo "${{ secrets.DOCKER_HUB_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_HUB_USERNAME }}" --password-stdin
- name: Push Docker Image to Docker Hub
run: |
docker push ${{ secrets.DOCKER_HUB_USERNAME }}/backend-server:latest
- name: Deploy to Application Server
run: |
mkdir -p ~/.ssh
echo "${{ secrets.AWS_APPLICATION_SERVER_SSH_KEY }}" > ~/.ssh/app_server.pem
chmod 600 ~/.ssh/app_server.pem
ssh-keyscan -H ${{ secrets.AWS_APPLICATION_SERVER_HOST }} >> ~/.ssh/known_hosts
ssh -i ~/.ssh/app_server.pem ubuntu@${{ secrets.AWS_APPLICATION_SERVER_HOST }} << 'EOF'
docker stop web-container || true
docker rm web-container || true
docker pull ${{ secrets.DOCKER_HUB_USERNAME }}/backend-server:latest
echo "${{ secrets.ENV_FILE }}" > .env
docker run -d --name web-container --env-file .env -p 8080:8080 ${{ secrets.DOCKER_HUB_USERNAME }}/backend-server:latest
EOF